#include "StdAfx.h"
#include "client.hpp"

namespace fly {

	namespace jld{

		namespace client {

			client::client(cln_handler* handler, size_t pool_size,  const std::string& addr,const std::string& port,const size_t conn_num)
				:signals_(is_pool->get_io_service()),
				connection_manager_(),
				handler_(handler),
				new_connection_(),
				connect_number_(conn_num)
			{

				signals_.add(SIGINT);
				signals_.add(SIGTERM);
#if defined(SIGQUIT)
				signals_.add(SIGQUIT);
#endif // defined(SIGQUIT)
				signals_.async_wait(boost::bind(&client::clean_all, this));
				// Start an asynchronous resolve to translate the server and service names
				// into a list of endpoints.

				ip::tcp::resolver resolver(is_pool->get_io_service());
				ip::tcp::resolver::query query(addr, port);
				system::error_code err;
				ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query, err);
				if (err)
				{
					LOG_T_ERR(err.message());
					signals_.cancel();
					return;
				}

				ansy_connect(err, endpoint_iterator);
			}

			void client::run()
			{
				LOG_INFO("cln start run.");
				is_pool->run();
			}

			void client::handle_connect(const boost::system::error_code& err, ip::tcp::resolver::iterator& endpoint_iterator)
			{
				if (!err)
				{
					// The connection was successful. Send the request.
					connection_manager_.start(new_connection_);
				}
				else
				{
					LOG_T_ERR(err.message());
				}
				if(connection_manager_.connection_size() < connect_number_)
				{
					ansy_connect(err, endpoint_iterator);
				}
			}

			void client::ansy_connect(const boost::system::error_code& err, ip::tcp::resolver::iterator& endpoint_iterator)
			{
				if (!err)
				{
					new_connection_.reset(new connection(is_pool->get_io_service(),connection_manager_, handler_));
					// Attempt a connection to each endpoint in the list until we
					// successfully establish a connection.
					boost::asio::async_connect(new_connection_->socket(), endpoint_iterator,
						boost::bind(&client::handle_connect, this,
						boost::asio::placeholders::error, endpoint_iterator));
				} else
				{
					LOG_T_ERR(err.message());
				}

			}

			void client::clean_all()
			{
				connection_manager_.stop_all();
				is_pool->stop();
			}
		}
	}
}